Function: c-forward-<>-arglist-recur
c-forward-<>-arglist-recur is a byte-compiled function defined in
cc-engine.el.gz.
Signature
(c-forward-<>-arglist-recur ALL-TYPES)
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/cc-engine.el.gz
(defun c-forward-<>-arglist-recur (all-types)
;; Recursive part of `c-forward-<>-arglist'.
;;
;; This function might do hidden buffer changes.
(let ((start (point)) res pos
;; Cover this so that any recorded found type ranges are
;; automatically lost if it turns out to not be an angle
;; bracket arglist. It's propagated through the return value
;; on successful completion.
(c-record-found-types c-record-found-types)
(syntax-table-prop-on-< (c-get-char-property (point) 'syntax-table))
;; List that collects the positions after the argument
;; separating ',' in the arglist.
arg-start-pos)
;; If the '<' has paren open syntax then we've marked it as an angle
;; bracket arglist before, so skip to the end.
(if (and (not c-parse-and-markup-<>-arglists)
syntax-table-prop-on-<)
(progn
(forward-char)
(if (and (c-go-up-list-forward)
(eq (char-before) ?>))
t
;; Got unmatched paren angle brackets. We don't clear the paren
;; syntax properties and retry, on the basis that it's very
;; unlikely that paren angle brackets become operators by code
;; manipulation. It's far more likely that it doesn't match due
;; to narrowing or some temporary change.
(goto-char start)
nil))
(forward-char) ; Forward over the opening '<'.
(unless (and (looking-at c-<-op-cont-regexp)
(not (looking-at c-<-pseudo-digraph-cont-regexp)))
;; go forward one non-alphanumeric character (group) per iteration of
;; this loop.
(while (and
(progn
(c-forward-syntactic-ws)
(when (or (and c-record-type-identifiers all-types)
(not (equal c-inside-<>-type-key
(concat
"\\(" regexp-unmatchable "\\)"))))
(c-forward-syntactic-ws)
(cond
((eq (char-after) ??)
(forward-char))
((and (looking-at c-identifier-start)
(not (looking-at c-keywords-regexp)))
(if (or (and all-types c-record-type-identifiers)
(c-major-mode-is 'java-mode))
;; All encountered identifiers are types, so set the
;; promote flag and parse the type.
(let ((c-promote-possible-types t)
(c-record-found-types t))
(c-forward-type))
(c-forward-over-token-and-ws))))
(c-forward-syntactic-ws)
(when (looking-at c-inside-<>-type-key)
(goto-char (match-end 1))
(c-forward-syntactic-ws)
(let ((c-promote-possible-types t)
(c-record-found-types t))
(c-forward-type))
(c-forward-syntactic-ws)))
(setq pos (point)) ; e.g. first token inside the '<'
;; Note: These regexps exploit the match order in \| so
;; that "<>" is matched by "<" rather than "[^>:-]>".
(c-syntactic-re-search-forward
;; Stop on ',', '|', '&', '+' and '-' to catch
;; common binary operators that could be between
;; two comparison expressions "a<b" and "c>d".
;; 2016-02-11: C++11 templates can now contain arithmetic
;; expressions, so template detection in C++ is now less
;; robust than it was.
c-<>-notable-chars-re
nil t t))
(cond
((eq (char-before) ?>)
;; Either an operator starting with '>' or the end of
;; the angle bracket arglist.
(if (save-excursion
(c-backward-token-2)
(looking-at c-multichar->-op-not->>->>>-regexp))
(progn
(goto-char (match-end 0))
t) ; Continue the loop.
;; The angle bracket arglist is finished.
(when c-parse-and-markup-<>-arglists
(while arg-start-pos
(c-put-c-type-property (1- (car arg-start-pos))
'c-<>-arg-sep)
(setq arg-start-pos (cdr arg-start-pos)))
(when (and (not syntax-table-prop-on-<)
(c-get-char-property (1- (point))
'syntax-table))
;; Clear the now spuriously matching < of its
;; syntax-table property. This could happen on
;; inserting "_cast" into "static <" with C-y.
(save-excursion
(and (c-go-list-backward)
(eq (char-after) ?<)
(c-truncate-lit-pos-cache (point))
(c-unmark-<->-as-paren (point)))))
(c-mark-<-as-paren start)
(c-mark->-as-paren (1- (point)))
(c-truncate-lit-pos-cache start))
(setq res t)
nil)) ; Exit the loop.
((eq (char-before) ?<)
;; Either an operator starting with '<' or a nested arglist.
(setq pos (point))
(let (id-start id-end subres keyword-match)
(cond
;; The '<' begins a multi-char operator.
((and (looking-at c-<-op-cont-regexp)
(not (looking-at c-<-pseudo-digraph-cont-regexp)))
(goto-char (match-end 0)))
;; We're at a nested <.....>
((progn
(backward-char) ; to the '<'
(and
(save-excursion
;; There's always an identifier before an angle
;; bracket arglist, or a keyword in `c-<>-type-kwds'
;; or `c-<>-arglist-kwds'.
(c-backward-syntactic-ws)
(setq id-end (point))
(c-simple-skip-symbol-backward)
(when (or (setq keyword-match
(looking-at c-opt-<>-sexp-key))
(not (looking-at c-keywords-regexp)))
(setq id-start (point))))
(setq subres
(let ((c-promote-possible-types t)
(c-record-found-types t))
(c-forward-<>-arglist-recur
(and keyword-match
(c-keyword-member
(c-keyword-sym (match-string 1))
'c-<>-type-kwds))))))
(or subres (goto-char pos))
subres)
;; It was an angle bracket arglist.
(setq c-record-found-types subres)
;; Record the identifier before the template as a type
;; or reference depending on whether the arglist is last
;; in a qualified identifier.
(when (and c-record-type-identifiers
(not keyword-match))
(if (and c-opt-identifier-concat-key
(progn
(c-forward-syntactic-ws)
(looking-at c-opt-identifier-concat-key)))
(c-record-ref-id (cons id-start id-end))
(c-record-type-id (cons id-start id-end)))))
;; At a "less than" operator.
(t
;; (forward-char) ; NO! We've already gone over the <.
)))
t) ; carry on looping.
((and
(eq (char-before) ?\()
(c-go-up-list-forward)
(eq (char-before) ?\))))
((and (not c-restricted-<>-arglists)
(or (and (eq (char-before) ?&)
(not (eq (char-after) ?&)))
(eq (char-before) ?,)))
;; Just another argument. Record the position. The
;; type check stuff that made us stop at it is at
;; the top of the loop.
(setq arg-start-pos (cons (point) arg-start-pos)))
(t
;; Got a character that can't be in an angle bracket
;; arglist argument. Abort using `throw', since
;; it's useless to try to find a surrounding arglist
;; if we're nested.
(throw 'angle-bracket-arglist-escape nil))))))
(if res
(or c-record-found-types t)))))